//
//  TXProgressManager.swift
//  SwiftLibrary
//
//  Created by xicheng on 16/3/9.
//  Copyright © 2016年 taurusxi. All rights reserved.
//

import UIKit

import SVProgressHUD

//import SnapKit

enum TXProgressStatus: Int {
  case main
  case progress
  case empty
  case error
}

protocol _ProgressViewInterface {
}

class _ProgressView: UIButton, _ProgressViewInterface {
  
  override init(frame: CGRect) {
    super.init(frame: frame)
    self.setupView()
    self.addTarget(self, action: #selector(_ProgressView.progressClick), for: .touchDragInside)
  }
  
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
  
  @objc fileprivate func progressClick() {
    TXLogInfo("_ProgressView_Click")
  }
  
  fileprivate func setupView() {
    self.backgroundColor = UIColor.white
    let progressView: TX_SVIndefiniteAnimatedView = TX_SVIndefiniteAnimatedView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
    progressView.radius = 25
    progressView.strokeColor = UIColor.ondC5Color()
    progressView.strokeThickness = 4
    progressView.sizeToFit()
    //    let progress = UIActivityIndicatorView.init(activityIndicatorStyle: UIActivityIndicatorViewStyle.WhiteLarge
    //    )
    //    progress.startAnimating()
    //    progress.sizeToFit()
    //    SVProgressHUD.show()
    progressView.center = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2)
    self.addSubview(progressView)
  }
}

class _ErrorView: UIView {
  
  fileprivate weak var delegate: TXProgressManager? = nil
  
  override init(frame: CGRect) {
    super.init(frame: frame)
    self.setupView()
    //    self.addTarget(self, action: "progressClick", forControlEvents: .TouchDragInside)
  }
  
  convenience init(frame: CGRect, delegate: TXProgressManager) {
    self.init(frame: frame)
    self.delegate = delegate
  }
  
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
  
  @objc fileprivate func progressClick() {
    TXLogInfo( "_ErrorView_Click")
  }
  
  fileprivate func setupView() {
    self.backgroundColor = UIColor.bgColor()
    
    let contentView = UIView(frame: CGRect(x: 0, y: 0, width: 260, height: 210))
    
    self.addSubview(contentView)
    contentView.center.x = self.frame.width / 2
    contentView.center.y = self.frame.height / 2
    
    let imageView = UIImageView(image: UIImage(named: "wifi"))
    contentView.addSubview(imageView)
    imageView.center.x = contentView.frame.width / 2
    
    let tipLabel: UILabel = UILabel()
    tipLabel.text = "网络不给力哦，请刷新重试"
    tipLabel.textColor = UIColor.ondC5Color()
    tipLabel.sizeToFit()
    contentView.addSubview(tipLabel)
    tipLabel.center.x = contentView.frame.width / 2
    tipLabel.frame.bottom = contentView.frame.height - 45 - 27
    
    let btn: NormalMDSingleButton = NormalMDSingleButton(frame: CGRect(x: 0, y: contentView.frame.height - 45, width: contentView.frame.width, height: 45))
    
    btn.setTitle("重新加载", for: .normal)
    btn.titleLabel?.font = UIFont.systemFont(ofSize: 22)
    btn.setTitleColor(UIColor.white, for: .normal)
    btn.backgroundColor = UIColor.ondC1Color()
    
    btn.setSingleClickListener() {
      [unowned self] in
      self.delegate?.baseVC?.errorViewClick()
    }
    contentView.addSubview(btn)
  }
}

class _EmptyView: UIView {
  
  fileprivate weak var delegate: TXProgressManager? = nil
  
  var emptyTitle: String? {
    didSet {
      emptyLabel.text = emptyTitle
      emptyLabel.sizeToFit()
      emptyLabel.center = CGPoint(x: self.width/2, y: self.height/2)
    }
  }
  
  override init(frame: CGRect) {
    super.init(frame: frame)
    self.setupView()
  }
  
  convenience init(frame: CGRect, delegate: TXProgressManager) {
    self.init(frame: frame)
    self.delegate = delegate
  }
  
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
  
  @objc fileprivate func emptyClick() {
    TXLogInfo("_emptyClick_Click")
  }
  
  fileprivate func setupView() {
    self.backgroundColor = UIColor.bgColor()
    
    self.addSubview(emptyLabel)
    //    emptyLabel.snp_makeConstraints { (make) -> Void in
    //      make.centerX.equalTo(self)
    //      make.top.equalTo(imageView.snp_bottom).offset(10)
    //      make.width.equalTo(300)
    //      make.height.equalTo(35)
    //    }
  }
  fileprivate lazy var emptyLabel: UILabel = {
    let label = UILabel()
    label.textAlignment = NSTextAlignment.center
    label.font = UIFont.systemFont(ofSize: 14)
    label.textColor = UIColor.ondC1Color()
    label.numberOfLines = 0
    return label
  }()
}

let MIN_ANIMATION_TIME = 0.6

class TXProgressManager {
  
  fileprivate var status: TXProgressStatus = .progress
  
  var progressView: _ProgressView? = nil
  
  fileprivate var errorView: _ErrorView? = nil
  
  fileprivate var emptyView: _EmptyView? = nil
  
  fileprivate weak var mainView: UIView? = nil
  
  fileprivate var currentProgreesStartTime: TimeInterval = 0
  
  fileprivate var needLoading: Bool = true
  
  fileprivate weak var baseVC: TXBaseViewController? = nil
  
  internal var emptyTitle: String? = nil
  
  internal var showProgressFlag: Bool = true {
    didSet {
      self.progressView?.isHidden = !showProgressFlag
    }
  }
  
  init(baseVC: TXBaseViewController?) {
    self.baseVC = baseVC
    if let vc = self.baseVC {
      self.mainView = vc.view
    }
  }
  
  fileprivate func doByDelay(_ block: @escaping () -> ()) {
    let currentTime = CACurrentMediaTime()
    if (currentTime - currentProgreesStartTime < MIN_ANIMATION_TIME) {
      Timer.schedule(delay: (currentProgreesStartTime + MIN_ANIMATION_TIME - currentTime)) {
        handler in
        block()
      }
    } else {
      block()
    }
  }
  
  fileprivate func translationView(fromView f: UIView?, toView t: UIView?, block: (() -> ())? = nil) {
    if let fromView = f, let toView = t {
      fromView.alpha = 1.0
      toView.alpha = 1.0
      toView.isHidden = false
      UIView.animate(withDuration: MIN_ANIMATION_TIME, animations: {
        fromView.alpha = 0.0
        }, completion: {
          finished in
          toView.isHidden = false
          if toView is _ErrorView {
            TXLogError("_ErrorView__hidden__false")
          }
          
          if let b = block {
            b()
          }
      })
    }
  }
  
  fileprivate func hideView(_ view: UIView?) {
    if let v = view {
      if v.isHidden == false {
        v.isHidden = true
      }
    }
  }
  fileprivate func checkProgress() {
    
    guard let baseVC = self.baseVC else {
      return
    }
    
    if self.progressView == nil {
      
      self.progressView = _ProgressView(frame: baseVC.view.frame)
      
    }
    
    if self.progressView?.superview == nil {
      baseVC.view.addSubview(self.progressView!)
      //      baseVC.view.bringSubviewToFront(self.progressView!)
      self.status = .progress
      baseVC.view.bringSubview(toFront: self.progressView!)
      baseVC.view.bringSubview(toFront: baseVC.naviBar)
    }
  }
  
  fileprivate func checkErrorView() {
    guard let baseVC = self.baseVC else {
      return
    }
    if self.errorView == nil {
      
      self.errorView = _ErrorView(frame: baseVC.view.frame, delegate: self)
      
    }
    if self.errorView?.superview == nil {
      TXLogError("errorView__removeFromSuperview:\(self.errorView)__\(self.progressView)")
      
      baseVC.view.insertSubview(self.errorView!, belowSubview: self.progressView!)
    }
  }
  
  fileprivate func checkEmptyView(_ emptyTitleStr: String) {
    guard let baseVC = self.baseVC else {
      return
    }
    
    if self.emptyView == nil {
      self.emptyView = _EmptyView(frame: baseVC.view.frame, delegate: self)
    }
    
    if self.emptyView?.superview == nil {
      baseVC.view.insertSubview(self.emptyView!, belowSubview: self.progressView!)
    }
    emptyView?.emptyTitle = emptyTitleStr
  }
  
  internal func setProgressView(progressView view: _ProgressViewInterface) {
    if self.progressView != nil && self.progressView?.superview != nil {
      self.progressView?.removeFromSuperview()
    }
    self.progressView = view as? _ProgressView
    self.mainView?.addSubview(self.progressView!)
    self.mainView?.bringSubview(toFront: self.progressView!)
  }
  
  internal func setEmptyView(emptyView view: UIView) {
  }
  
  internal func setErrorView(errorView view: UIView) {
  }
  
  fileprivate func statusTranslation(fromView f: UIView?, toVoew t: UIView?, hideView hideList: [UIView?], block: (() -> ())? = nil) {
    guard let _ = self.baseVC else {
      return
    }
    
    for view in hideList {
      hideView(view)
    }
    
    translationView(fromView: f, toView: t) {
      if let b = block {
        b()
      }
    }
  }
}

extension TXProgressManager {
  internal func toMain() {
    TXLogError("TXProgressManager_toMain")
    switch status {
    case .progress :
      guard let baseVC = self.baseVC else {
        return
      }
      
      doByDelay {
        self.statusTranslation(fromView: self.progressView, toVoew: baseVC.view, hideView: [self.emptyView, self.errorView]) {
          self.progressView?.isHidden = true
          self.status = .main
        }
      }
      break
    case .main:
      break
    case .empty:
      guard let baseVC = self.baseVC else {
        return
      }
      self.statusTranslation(fromView: self.emptyView, toVoew: baseVC.view, hideView: [self.progressView, self.errorView]) {
        self.emptyView?.isHidden = true
        self.status = .main
      }
      break
      
    case .error:
      guard let baseVC = self.baseVC else {
        return
      }
      self.statusTranslation(fromView: self.errorView, toVoew: baseVC.view, hideView: [self.progressView, self.emptyView]) {
        self.errorView?.isHidden = true
        self.status = .main
      }
      
      break
    }
  }
  
  internal func toError() {
    checkProgress()
    switch status {
    case .progress :
      self.checkErrorView()
      
      doByDelay {
        self.statusTranslation(fromView: self.progressView, toVoew: self.errorView, hideView: [self.emptyView]) {
          self.progressView?.isHidden = true
          TXLogError("self.errorView.hidden:\(self.errorView?.isHidden)__alpha:\(self.errorView?.alpha)")
          self.status = .error
        }
      }
      break
    case .main:
      self.checkErrorView()
      
      doByDelay {
        self.statusTranslation(fromView: self.progressView, toVoew: self.errorView, hideView: [self.emptyView]) {
          self.progressView?.isHidden = true
          TXLogError("self.errorView.hidden:\(self.errorView?.isHidden)__alpha:\(self.errorView?.alpha)")
          self.status = .error
        }
      }
      break
    case .empty:
      break
      
    case .error:
      break
    }
  }
  
  internal func toEmpty(_ emptyTitleStr: String = "") {
    switch status {
    case .progress :
      
      self.checkEmptyView(emptyTitleStr)
      doByDelay {
        self.statusTranslation(fromView: self.progressView, toVoew: self.emptyView, hideView: [self.errorView]) {
          self.progressView?.isHidden = true
          self.status = .empty
        }
      }
      break
    case .main:
      
      self.checkEmptyView(emptyTitleStr)
      doByDelay {
        self.statusTranslation(fromView: self.progressView, toVoew: self.emptyView, hideView: [self.errorView]) {
          self.progressView?.isHidden = true
          self.status = .empty
        }
      }
      
      break
    case .empty:
      //      self.checkEmptyView(emptyTitleStr)
      //      doByDelay {
      //        self.statusTranslation(fromView: self.progressView, toVoew: self.emptyView, hideView: [self.errorView]) {
      //          self.progressView?.hidden = true
      //          self.status = .Empty
      //        }
      //      }
      
      break
      
    case .error:
      break
    }
  }
  
  internal func toProgress() {
    checkProgress()
    switch status {
      
    case .main:
      break
    case .progress:
      break
    case .empty:
      guard let _ = self.baseVC else {
        return
      }
      status = .progress
      currentProgreesStartTime = CACurrentMediaTime()
      statusTranslation(fromView: self.emptyView, toVoew: self.progressView, hideView: [self.errorView]) {
        self.emptyView?.isHidden = true
        self.emptyView?.removeFromSuperview()
      }
      break
    case .error:
      guard let _ = self.baseVC else {
        return
      }
      status = .progress
      currentProgreesStartTime = CACurrentMediaTime()
      statusTranslation(fromView: self.errorView, toVoew: self.progressView, hideView: [self.emptyView]) {
        self.errorView?.isHidden = true
        self.errorView?.removeFromSuperview()
      }
      break
    }
    
    guard let mainView = self.mainView else {
      return
    }
    
    if progressView == nil {
      progressView = _ProgressView(frame: mainView.frame)
      TXLogError("\(mainView.frame)")
      mainView.addSubview(progressView!)
    }
    mainView.bringSubview(toFront: progressView!)
  }
}
